package org.springtest.test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Component
public class AccountServiceImpl implements AccountService {
	//@Autowired
	PasswordEncoder passwordEncoder;

	//@Autowired
	SaltSource saltSource;
	
	private List<Account> accounts;
	
	public AccountServiceImpl() {
		//AppContext.getAutowireCapableBeanFactory().autowireBean(passwordEncoder);
	}
	
	private void Initialize() {
		if ((accounts == null)
			&& (passwordEncoder != null)
			&& (saltSource != null)) {
			accounts = new ArrayList<Account>();
			
			Account acc =  new Administrator("pawel", "password", true, true,
		            true, true, new ArrayList<GrantedAuthority>());
			//acc.setId(7);
			//acc.setUsername("pawel");
			//acc.setPassword(passwordEncoder.encodePassword("password", saltSource));
			accounts.add(acc);
			
			System.out.println("user:'" + acc.getUsername() + "'");
			System.out.println("password:'" + acc.getPassword() + "'");
		}
	}

	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;		
		Initialize();
	}

	public void setSaltSource(SaltSource saltSource) {
		this.saltSource = saltSource;
		Initialize();
	}	
		
	//@Override
	public void registerAccount(Account account, List<AccountRole> ar)
			throws UserExistsException {
		
		if (passwordEncoder == null)
			System.out.println("passwordEncoder is null");
		else
			System.out.println("passwordEncoder is not null");
		
		if (saltSource == null)
			System.out.println("saltSource is null");
		else
			System.out.println("saltSource is not null");
				
		try {
			loadUserByUsername(account.getUsername());
		} catch (UsernameNotFoundException une) {			
			account.setPassword(passwordEncoder.encodePassword(account
					.getPassword(), saltSource));
			for (AccountRole arole : ar) {
				account.addAccountRole(arole);
			}
			
			accounts.add(account);
			return;
		}
		
		throw new UserExistsException();
	}

	//@Override
	public Collection<Account> listAccounts(Collection<AccountRole> roles) {
		// TODO: uwzglednic role
		return accounts;
	}

	//@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		try {
			for (Account ac : accounts) {
				if (ac.getUsername().equals(username))
					return ac;
			}
			
			throw new UserNotFoundException();
		} catch (UserNotFoundException e) {
			throw new UsernameNotFoundException(username);
		}
	}

}
